home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifcico / emsi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-10  |  10.1 KB  |  523 lines

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "xutil.h"
  5. #include "lutil.h"
  6. #include "ttyio.h"
  7. #include "session.h"
  8. #include "statetbl.h"
  9. #include "config.h"
  10. #include "emsi.h"
  11. #include "nodelist.h"
  12.  
  13. #define LOCAL_PROTOS (ZMO | ZAP)
  14.  
  15. extern int janus(void);
  16. extern int rxwazoo(void);
  17. extern int txwazoo(void);
  18. extern unsigned short crc16(char*,int);
  19. extern char *version,*reldate;
  20. extern void rdoptions(node *);
  21.  
  22. static int rxemsi(void);
  23. static int txemsi(void);
  24. static char *intro;
  25. static int caller;
  26.  
  27. int emsi_local_lcodes;
  28. int emsi_remote_lcodes;
  29. int emsi_local_protos;
  30. int emsi_remote_protos;
  31. int emsi_local_opts;
  32. int emsi_remote_opts;
  33. char *emsi_local_password;
  34. char *emsi_remote_password;
  35. char emsi_remote_comm[4]="8N1";
  36.  
  37. int rx_emsi(data)
  38. char *data;
  39. {
  40.     int rc;
  41.     fa_list *tmp,*tmr;
  42.     int denypw=0;
  43.     node *nlent;
  44.  
  45.     loginf("start inbound EMSI session");
  46.     emsi_local_lcodes=0;
  47.     if (localoptions & NOPUA) emsi_local_lcodes |= PUP;
  48.     emsi_remote_lcodes=0;
  49.     emsi_local_protos=LOCAL_PROTOS;
  50.     if (localoptions & NOZMODEM) emsi_local_protos &= ~(ZMO|ZAP|DZA);
  51.     if (localoptions & NOZEDZAP) emsi_local_protos &= ~ZAP;
  52.     if (localoptions & NOJANUS) emsi_local_protos &= ~JAN;
  53.     if (localoptions & NOHYDRA) emsi_local_protos &= ~HYD;
  54.     emsi_remote_protos=0;
  55.     emsi_local_opts=XMA;
  56.     emsi_remote_opts=0;
  57.     emsi_local_password=NULL;
  58.     emsi_remote_password=NULL;
  59.     intro=data+2;
  60.     caller=0;
  61.  
  62.     if ((rc=rxemsi())) return rc;
  63.  
  64.     if (localoptions & NOFREQS) emsi_local_opts |= NRQ;
  65.  
  66.     debug(10,"local  lcodes 0x%04x, protos 0x%04x, opts 0x%04x",
  67.         emsi_local_lcodes,emsi_local_protos,emsi_local_opts);
  68.     debug(10,"remote lcodes 0x%04x, protos 0x%04x, opts 0x%04x",
  69.         emsi_remote_lcodes,emsi_remote_protos,emsi_remote_opts);
  70.  
  71.     emsi_local_protos &= emsi_remote_protos;
  72.     if (emsi_local_protos & HYD) emsi_local_protos &= HYD;
  73.     else if (emsi_local_protos & JAN) emsi_local_protos &= JAN;
  74.     else if (emsi_local_protos & ZAP) emsi_local_protos &= ZAP;
  75.     else if (emsi_local_protos & ZMO) emsi_local_protos &= ZMO;
  76.     else if (emsi_local_protos & DZA) emsi_local_protos &= DZA;
  77.     else if (emsi_local_protos & KER) emsi_local_protos &= KER;
  78.  
  79.     emsi_local_password=NULL;
  80.  
  81.     for (tmr=remote;tmr;tmr=tmr->next)
  82.     if (((nlent=getnlent(tmr->addr))) &&
  83.         (nlent->pflag != DUMMY))
  84.     {
  85.         loginf("remote is a listed system");
  86.         inbound=listinbound;
  87.         rdoptions(nlent);
  88.         break;
  89.     }
  90.  
  91.     for (tmp=pwlist;tmp;tmp=tmp->next)
  92.     for (tmr=remote;tmr;tmr=tmr->next)
  93.     if (metric(tmr->addr,tmp->addr) == 0)
  94.     {
  95.         if (strncasecmp(emsi_remote_password,tmp->addr->name,8) != 0)
  96.         {
  97.             denypw=1;
  98.             loginf("remote gave password \"%s\", expected \"%s\"",
  99.                 emsi_remote_password,tmp->addr->name);
  100.             emsi_local_password="BAD_PASSWORD";
  101.             emsi_local_lcodes=HAT;
  102.         }
  103.         else
  104.         {
  105.             emsi_local_password=tmp->addr->name;
  106.             inbound=protinbound;
  107.             loginf("remote gave correct password, protected EMSI session");
  108.         }
  109.     }
  110.  
  111.     debug(10,"local  lcodes 0x%04x, protos 0x%04x, opts 0x%04x",
  112.         emsi_local_lcodes,emsi_local_protos,emsi_local_opts);
  113.  
  114.     if ((rc=txemsi())) return rc;
  115.  
  116.     if (denypw || (emsi_local_protos == 0))
  117.     {
  118.         loginf("refusing remote: %s",
  119.             emsi_local_protos?"bad password presented":
  120.                 "no common protocols");
  121.         return 0;
  122.     }
  123.     if ((emsi_remote_opts & NRQ) == 0) session_flags |= SESSION_WAZOO;
  124.     else session_flags &= ~SESSION_WAZOO;
  125.     if (emsi_local_protos & JAN) return janus();
  126.     else return rxwazoo();
  127. }
  128.  
  129. int tx_emsi(data)
  130. char* data;
  131. {
  132.     int rc;
  133.  
  134.     loginf("start outbound EMSI session");
  135.     emsi_local_lcodes=PUA;
  136.     if (localoptions & NOPUA)
  137.     {
  138.         emsi_local_lcodes |= PUP;
  139.         emsi_local_lcodes &= ~PUA;
  140.     }
  141.     emsi_remote_lcodes=0;
  142.     emsi_local_protos=LOCAL_PROTOS;
  143.     if (localoptions & NOZMODEM) emsi_local_protos &= ~(ZMO|ZAP|DZA);
  144.     if (localoptions & NOZEDZAP) emsi_local_protos &= ~ZAP;
  145.     if (localoptions & NOJANUS) emsi_local_protos &= ~JAN;
  146.     if (localoptions & NOHYDRA) emsi_local_protos &= ~HYD;
  147.     emsi_remote_protos=0;
  148.     emsi_local_opts=XMA;
  149.     emsi_remote_opts=0;
  150.     emsi_local_password=NULL;
  151.     emsi_remote_password=NULL;
  152.     intro=data+2;
  153.     caller=1;
  154.     emsi_local_password=NULL;
  155.  
  156.     debug(10,"local  lcodes 0x%04x, protos 0x%04x, opts 0x%04x",
  157.         emsi_local_lcodes,emsi_local_protos,emsi_local_opts);
  158.  
  159.     if ((rc=txemsi())) return rc;
  160.     else if ((rc=rxemsi())) return rc;
  161.  
  162.     debug(10,"remote lcodes 0x%04x, protos 0x%04x, opts 0x%04x",
  163.         emsi_remote_lcodes,emsi_remote_protos,emsi_remote_opts);
  164.  
  165.     if ((emsi_remote_protos == 0) || (emsi_remote_lcodes & HAT))
  166.     {
  167.         loginf("remote refused us: %s",
  168.             emsi_remote_protos?"traffic held":"no common protos");
  169.         return 0;
  170.     }
  171.     emsi_local_protos &= emsi_remote_protos;
  172.     if ((emsi_remote_opts & NRQ) == 0) session_flags |= SESSION_WAZOO;
  173.     else session_flags &= ~SESSION_WAZOO;
  174.     if (emsi_local_protos & JAN) return janus();
  175.     else return txwazoo();
  176. }
  177.  
  178. SM_DECL(rxemsi,"rxemsi")
  179. SM_STATES
  180.     waitpkt,waitchar,checkemsi,getdat,checkpkt,checkdat,
  181.     sendnak,sendack
  182. SM_NAMES
  183.     "waitpkt","waitchar","checkemsi","getdat","checkpkt","checkdat",
  184.     "sendnak","sendack"
  185. SM_EDECL
  186.  
  187.     int c;
  188.     unsigned short lcrc,rcrc;
  189.     int len;
  190.     int standby=0,tries=0;
  191.     char buf[13],*p;
  192.     char *databuf=NULL;
  193.  
  194.     p=buf;
  195.     databuf=xstrcpy(intro);
  196.  
  197. SM_START(checkpkt)
  198.  
  199. SM_STATE(waitpkt)
  200.  
  201.     standby=0;
  202.     SM_PROCEED(waitchar);
  203.  
  204. SM_STATE(waitchar)
  205.  
  206.     c=GETCHAR(8);
  207.     if (c == TIMEOUT)
  208.     {
  209.         if (++tries > 6)
  210.         {
  211.             loginf("too many tries waiting EMSI handshake");
  212.             SM_ERROR;
  213.         }
  214.         else {SM_PROCEED(sendnak);}
  215.     }
  216.     else if (c < 0)
  217.     {
  218.         SM_ERROR;
  219.     }
  220.     else if ((c >= ' ') && (c <= '~'))
  221.     {
  222.         if (c == '*')
  223.         {
  224.             standby=1;
  225.             p=buf;
  226.             *p='\0';
  227.         }
  228.         else if (standby)
  229.         {
  230.             if ((p-buf) < (sizeof(buf)-1))
  231.             {
  232.                 *p++=c;
  233.                 *p='\0';
  234.             }
  235.             if ((p-buf) >= (sizeof(buf)-1))
  236.             {
  237.                 standby=0;
  238.                 SM_PROCEED(checkemsi);
  239.             }
  240.         }
  241.     }
  242.     else switch(c)
  243.     {
  244.     case DC1:    break;
  245.     case '\n':
  246.     case '\r':    standby=0;
  247.             break;
  248.     default:    standby=0;
  249.             debug(10,"got '%s' reading emsi",
  250.                 printablec(c));
  251.             break;
  252.     }
  253.  
  254.     SM_PROCEED(waitchar);
  255.  
  256. SM_STATE(checkemsi)
  257.  
  258.     debug(10,"rxemsi got: \"%s\"",buf);
  259.     if (strncasecmp(buf,"EMSI_DAT",8) == 0) {SM_PROCEED(getdat);}
  260.     else if (strncasecmp(buf,"EMSI_",5) == 0)
  261.     {
  262.         if (databuf) free(databuf);
  263.         databuf=xstrcpy(buf);
  264.         SM_PROCEED(checkpkt);
  265.     }
  266.     else
  267.     {
  268.         SM_PROCEED(waitpkt);
  269.     }
  270.  
  271. SM_STATE(getdat)
  272.  
  273.     debug(10,"try get emsi_dat packet starting with \"%s\"",buf);
  274.  
  275.     if (sscanf(buf+8,"%04x",&len) != 1)
  276.         {SM_PROCEED(sendnak);}
  277.  
  278.     len += 16; /* strlen("EMSI_DATxxxxyyyy"), include CRC */
  279.     if (databuf) free(databuf);
  280.     databuf=xmalloc(len+1);
  281.     strcpy(databuf,buf);
  282.     p=databuf+strlen(databuf);
  283.  
  284.     while (((p-databuf) < len) && ((c=GETCHAR(8)) >= 0))
  285.     {
  286.         debug(10,"got '%s'",printablec(c));
  287.         *p++=c;
  288.         *p='\0';
  289.     }
  290.  
  291.     debug(10,"len %d, databuf \"%s\"",len,databuf);
  292.  
  293.     if (c == TIMEOUT)
  294.     {
  295.         SM_PROCEED(sendnak);
  296.     }
  297.     else if (c < 0)
  298.     {
  299.         loginf("error while reading EMSI_DAT packet");
  300.         SM_ERROR;
  301.     }
  302.  
  303.     SM_PROCEED(checkdat);
  304.  
  305. SM_STATE(checkpkt)
  306.  
  307.     if (strncasecmp(databuf,"EMSI_DAT",8) == 0)
  308.     {
  309.         SM_PROCEED(checkdat);
  310.     }
  311.  
  312.     lcrc=crc16(databuf,8);
  313.     sscanf(databuf+8,"%04hx",&rcrc);
  314.     if (lcrc != rcrc)
  315.     {
  316.         loginf("got EMSI packet \"%s\" with bad crc: %04x/%04x",
  317.             printable(databuf,0),lcrc,rcrc);
  318.         SM_PROCEED(sendnak);
  319.     }
  320.     if (strncasecmp(databuf,"EMSI_HBT",8) == 0)
  321.     {
  322.         tries=0;
  323.         SM_PROCEED(waitpkt);
  324.     }
  325.     else if (strncasecmp(databuf,"EMSI_INQ",8) == 0)
  326.     {
  327.         SM_PROCEED(sendnak);
  328.     }
  329.     else
  330.     {
  331.         debug(10,"rxemsi ignores packet \"%s\"",databuf);
  332.         SM_PROCEED(waitpkt);
  333.     }
  334.  
  335. SM_STATE(checkdat)
  336.  
  337.     sscanf(databuf+8,"%04x",&len);
  338.     if (len != (strlen(databuf)-16))
  339.     {
  340.         loginf("bad EMSI_DAT length: %d/%d",len,strlen(databuf));
  341.         SM_PROCEED(sendnak);
  342.     }
  343.     sscanf(databuf+strlen(databuf)-4,"%04hx",&rcrc);
  344.     *(databuf+strlen(databuf)-4)='\0';
  345.     lcrc=crc16(databuf,strlen(databuf));
  346.     if (lcrc != rcrc)
  347.     {
  348.         loginf("got EMSI_DAT packet \"%s\" with bad crc: %04x/%04x",
  349.             printable(databuf,0),lcrc,rcrc);
  350.         SM_PROCEED(sendnak);
  351.     }
  352.     if (scanemsidat(databuf+12) == 0)
  353.     {
  354.         SM_PROCEED(sendack);
  355.     }
  356.     else
  357.     {
  358.         logerr("could not parse EMSI_DAT packet \"%s\"",databuf);
  359.         SM_ERROR;
  360.     }
  361.  
  362. SM_STATE(sendnak)
  363.  
  364.     if (++tries > 6)
  365.     {
  366.         loginf("too many tries getting EMSI_DAT");
  367.         SM_ERROR;
  368.     }
  369.     if (caller)
  370.     {
  371.         PUTSTR("**EMSI_NAKEEC3\r\021");
  372.     }
  373.     else
  374.     {
  375.         PUTSTR("**EMSI_REQA77E\r\021");
  376.     }
  377.     SM_PROCEED(waitpkt);
  378.  
  379. SM_STATE(sendack)
  380.  
  381.     PUTSTR("**EMSI_ACKA490\r\021");
  382.     PUTSTR("**EMSI_ACKA490\r\021");
  383.     SM_SUCCESS;
  384.  
  385. SM_END
  386.  
  387.     free(databuf);
  388.  
  389. SM_RETURN
  390.  
  391.  
  392. SM_DECL(txemsi,"txemsi")
  393. SM_STATES
  394.     senddata,waitpkt,waitchar,checkpkt,sendack
  395. SM_NAMES
  396.     "senddata","waitpkt","waitchar","checkpkt","sendack"
  397. SM_EDECL
  398.  
  399.     int c;
  400.     unsigned short lcrc,rcrc;
  401.     int standby=0,tries=0;
  402.     char buf[13],*p;
  403.     char trailer[8];
  404.  
  405.     p=buf;
  406.     strncpy(buf,intro,sizeof(buf)-1);
  407.  
  408. SM_START(senddata)
  409.  
  410. SM_STATE(senddata)
  411.  
  412.     p=mkemsidat(caller);
  413.     PUTCHAR('*');
  414.     PUTCHAR('*');
  415.     PUTSTR(p);
  416.     sprintf(trailer,"%04X\r\021",crc16(p,strlen(p)));
  417.     PUTSTR(trailer);
  418.     free(p);
  419.     SM_PROCEED(waitpkt);
  420.  
  421. SM_STATE(waitpkt)
  422.  
  423.     standby=0;
  424.     SM_PROCEED(waitchar);
  425.  
  426. SM_STATE(waitchar)
  427.  
  428.     c=GETCHAR(8);
  429.     if (c == TIMEOUT)
  430.     {
  431.         if (++tries > 6)
  432.         {
  433.             loginf("too many tries sending EMSI");
  434.             SM_ERROR;
  435.         }
  436.         else {SM_PROCEED(senddata);}
  437.     }
  438.     else if (c < 0)
  439.     {
  440.         SM_ERROR;
  441.     }
  442.     else if ((c >= ' ') && (c <= '~'))
  443.     {
  444.         if (c == '*')
  445.         {
  446.             standby=1;
  447.             p=buf;
  448.             *p='\0';
  449.         }
  450.         else if (standby)
  451.         {
  452.             if ((p-buf) < (sizeof(buf)-1))
  453.             {
  454.                 *p++=c;
  455.                 *p='\0';
  456.             }
  457.             if ((p-buf) >= (sizeof(buf)-1))
  458.             {
  459.                 standby=0;
  460.                 SM_PROCEED(checkpkt);
  461.             }
  462.         }
  463.     }
  464.     else switch(c)
  465.     {
  466.     case DC1:    SM_PROCEED(waitchar);
  467.             break;
  468.     case '\n':
  469.     case '\r':    standby=0;
  470.             break;
  471.     default:    standby=0;
  472.             debug(10,"got '%s' from remote",
  473.                 printablec(c));
  474.             break;
  475.     }
  476.  
  477.     {SM_PROCEED(waitchar);}
  478.  
  479. SM_STATE(checkpkt)
  480.  
  481.     debug(10,"rxemsi got: \"%s\"",buf);
  482.     if (strncasecmp(buf,"EMSI_DAT",8) == 0)
  483.     {
  484.         SM_PROCEED(sendack);
  485.     }
  486.     else if (strncasecmp(buf,"EMSI_",5) == 0)
  487.     {
  488.         lcrc=crc16(buf,8);
  489.         sscanf(buf+8,"%04hx",&rcrc);
  490.         if (lcrc != rcrc)
  491.         {
  492.             loginf("got EMSI packet \"%s\" with bad crc: %04x/%04x",
  493.                 printable(buf,0),lcrc,rcrc);
  494.             SM_PROCEED(senddata);
  495.         }
  496.         if (strncasecmp(buf,"EMSI_REQ",8) == 0)
  497.         {
  498.             SM_PROCEED(waitpkt);
  499.         }
  500.         if (strncasecmp(buf,"EMSI_ACK",8) == 0)
  501.         {
  502.             SM_SUCCESS;
  503.         }
  504.         else
  505.         {
  506.             SM_PROCEED(senddata);
  507.         }
  508.     }
  509.     else
  510.     {
  511.             SM_PROCEED(waitpkt);
  512.     }
  513.  
  514. SM_STATE(sendack)
  515.  
  516.     PUTSTR("**EMSI_ACKA490\r\021");
  517.     PUTSTR("**EMSI_ACKA490\r\021");
  518. /*    SM_PROCEED(senddata); */
  519.     SM_PROCEED(waitpkt);
  520.  
  521. SM_END
  522. SM_RETURN
  523.